﻿using Microsoft.Extensions.DependencyInjection;
using Modules.System.Role;
using PmSoft;
using PmSoft.Exceptions;

namespace Modules.System.Menu
{
    /// <summary>
    /// 系统菜单业务逻辑类
    /// </summary>
    [UseDI(ServiceLifetime.Scoped)]
    public class MenuService
    {
        private readonly SysMenuRepository menuRepository;
        private readonly SysRoleMenuRepository roleMenuRepository;
        private readonly SysUserRoleRepository userRoleRepository;
        private readonly SysRoleRepository roleRepository;

        public MenuService(SysMenuRepository menuRepository,
            SysRoleMenuRepository roleMenuRepository,
            SysUserRoleRepository userRoleRepository,
            SysRoleRepository roleRepository)
        {
            this.menuRepository = menuRepository;
            this.roleMenuRepository = roleMenuRepository;
            this.userRoleRepository = userRoleRepository;
            this.roleRepository = roleRepository;
        }

        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <param name="menu"></param>
        public void CreateMenu(SysMenu menu)
        {
            menuRepository.Insert(menu);
        }

        /// <summary>
        /// 获取当前菜单IdTreePath
        /// </summary>
        /// <param name="menuId"></param>
        /// <returns></returns>
        public string GetTreePath(int menuId, int firstId, IEnumerable<SysMenu> data, string value = "")
        {
            if (menuId == 0) return menuId.ToString();
            foreach (var item in data)
            {
                if (item.MenuId == menuId && item.ParentId != 0)
                {
                    value += item.ParentId + ",";
                    return GetTreePath(item.ParentId, firstId, data, value); // 递归调用
                }
            }
            value += firstId + "," + 0;
            string[] numbers = value.Split(',');
            Array.Sort(numbers);
            string result = string.Join(",", numbers);
            return result;
        }

        /// <summary>
        /// 全量更新菜单
        /// </summary>
        /// <param name="menu"></param>
        public void UpdateMenu(SysMenu menu)
        {
            menuRepository.Update(menu);
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="menuId"></param>
        public void DeleteMenu(int menuId)
        {
            var menu = GetSysMenu(menuId);
            if (menu == null)
                throw new BusinessException("菜单信息不存在");
            if (GetAllMenus().Any(m => m.ParentId == menuId))
                throw new BusinessException($"“{menu.Name}”菜单存在一个或多个子菜单，请先删除所有子菜单");

            menuRepository.DeleteByEntityId(menuId);
        }

        /// <summary>
        /// 删除多个菜单
        /// </summary>
        /// <param name="menuIds"></param>
        public void DeleteMenus(IEnumerable<int> menuIds)
        {
            foreach (int menuId in menuIds)
                DeleteMenu(menuId);
        }

        /// <summary>
        /// 修改菜单显示状态
        /// </summary>
        /// <returns></returns>
        public bool UpdateMenuVisible(int menuId, bool isVisible)
        {
            var menu = GetSysMenu(menuId);
            if (menu == null)
                return false;
            return menuRepository.UpdateMenuVisible(menu, isVisible);
        }

        /// <summary>
        /// 获取菜单信息
        /// </summary>
        /// <param name="menuId"></param>
        /// <returns></returns>
        public SysMenu? GetSysMenu(int menuId)
        {
            return menuRepository.Get(menuId);
        }

        /// <summary>
        /// 用户拥有的菜单
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IEnumerable<SysMenu> GetUserMenus(int userId)
        {
            //这个不会慢
            var roles = userRoleRepository.GetUserRolesByUserId(userId);
            var roleIds = roles.Select(m => m.RoleId);
            //获取多个角色的菜单
            var roleMenus = roleMenuRepository.GetMenuIdsByRoleIds(roleIds);
            return menuRepository.PopulateEntitiesByEntityIds(roleMenus.Select(m => m.MenuId)).OrderBy(m => m.Sort);
        }

        /// <summary>
        /// 获取全部菜单
        /// </summary>
        /// <returns></returns>
        public IEnumerable<SysMenu> GetAllMenus()
        {
            return menuRepository.GetAll().OrderBy(m => m.Sort);
        }

        public IEnumerable<SysRoleMenu> GetAllRoleMenus()
        {
            return roleMenuRepository.GetAllRoleMenus();
        }
    }
}